﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Charades.Web.Models;

namespace Charades.Web.Helpers
{
	using System.Security.Cryptography;

	public static class FileHelper
	{
		private static readonly byte[] HashImageEmpty = { 12, 11, 203, 227, 217, 219, 205, 116, 5, 132, 23, 163, 38, 34, 118, 2 };

		public static List<PictureModel> GetPictureList(int page = 0)
		{
			var targetFolder = HttpContext.Current.Server.MapPath("~/pic");
			var files = Directory.GetFiles(targetFolder)
				.Select(x => new FileInfo(x)).Where(x => x.Name != "empty.png" && x.Length > 0)
				.OrderByDescending(x => x.LastWriteTimeUtc)
				.Skip(15 * page).Take(15)
				.Select(
					fileInfo =>
					{
						var id = fileInfo.Name.Substring(0, 8);
						var fileData = Base32Hepler.DecodeFrom32(
							fileInfo.Name.Replace(id, string.Empty)
										.Replace(fileInfo.Extension, string.Empty)
						).Split(' ').ToArray();
						var pictureUrl = new Uri(ServerSettings.RootUrl, "/pic/" + fileInfo.Name);
						return new PictureModel()
						{
							Id = id,
							PictureUrl = pictureUrl,
							Painter = fileData[0],
							Word = fileData[1],
							FileIsReady = true
						};
					})
				.ToList();
			return files;
		}

		public static PictureModel GetPicture(string id)
		{
			var model = new PictureModel();
			var targetFolder = HttpContext.Current.Server.MapPath("~/pic");
			var files = Directory.GetFiles(targetFolder, id + "*");

			if (files.Length == 1)
			{
				var fileInfo = new FileInfo(files[0]);

				if (!fileInfo.Name.StartsWith(id))
				{
					return null;
				}

				model.PictureUrl = new Uri(ServerSettings.RootUrl, "/pic/" + fileInfo.Name);
				model.FileIsReady = fileInfo.Length > 0;

				var fileData = Base32Hepler.DecodeFrom32(
					fileInfo.Name.Replace(id, string.Empty)
						.Replace(fileInfo.Extension, string.Empty)
					).Split(' ').ToArray();

				model.Painter = fileData[0];
				model.Word = fileData[1];
			}
			else
			{
				return null;
			}

			return model;
		}

		public static void SavePicture(string name, string imageData)
		{
			var targetFolder = HttpContext.Current.Server.MapPath("~/pic");
			var targetPath = Path.Combine(targetFolder, name + ".png");
			var fileInfo = new FileInfo(targetPath);

			if (!fileInfo.Exists || fileInfo.Length != 0)
			{
				return;
			}

			var byteArray = Convert.FromBase64String(imageData);

			Task.Run(() => SavePictureInternal(targetPath, byteArray));
		}

		private static void SavePictureInternal(string path, byte[] byteArray)
		{
			using (var md5 = MD5.Create())
			{
				var hashImage = md5.ComputeHash(byteArray);
				if (hashImage.SequenceEqual(HashImageEmpty))
				{
					File.Delete(path);
					return;
				}
			}

			var ms = new MemoryStream(byteArray);
			var image = Image.FromStream(ms);

			if (image.Height != 500 || image.Width != 500)
			{
				File.Delete(path);
				return;
			}

			var drawFormat = new StringFormat
			{
				Alignment = StringAlignment.Center,
				FormatFlags = StringFormatFlags.NoWrap
			};

			var graphic = Graphics.FromImage(image);

			var rectagleBrush = new SolidBrush(Color.FromArgb(50, Color.Black));
			graphic.FillRectangle(rectagleBrush, new Rectangle(430, 485, 70, 15));

			var textBrush = new SolidBrush(Color.White);
			var textFont = new Font("Verdana", 9, FontStyle.Bold);
			graphic.DrawString("drawpi.co", textFont, textBrush, 465, 485, drawFormat);

			image.Save(path, ImageFormat.Png);

			rectagleBrush.Dispose();
			textBrush.Dispose();
			textFont.Dispose();
			drawFormat.Dispose();
			graphic.Dispose();
			image.Dispose();
			ms.Dispose();
		}
	}
}